#ifndef RENDERTHREAD_H
#define RENDERTHREAD_H

#include <QObject>
#include <QThread>
#include <QSize>
#include "ffinclude.h"

class VideoPlayer;

/*
    渲染线程
*/
class RenderThread : public QThread
{
    Q_OBJECT
public:
    explicit RenderThread(VideoPlayer* player);
    ~RenderThread();

    void play();
    void pause();
    void stop();
    void step();

signals:
    void inited();
    void eos();
    void timeout();
    void error(const QString& err);

protected:
    void run();

private:
    void togglePauseState(bool pause);

    //视频
    bool createWindow();
    void destoryWindow();
    void renderNextVideoAndText(double *delayTime);
    void sdlRenderVideoAndText();   
    double syncVideo(double delay);
    void updateVideoClock( double pts, int64_t pos, int serial);
    void updateExternalClockSpeed();
    double computeDuration(Frame *vp, Frame *nextvp);
    inline int computeMod(int a, int b);
    void computeDisplayRect(SDL_Rect *rect, int pic_width, int pic_height, AVRational pic_sar);
    int uploadTexture(SDL_Texture **texture, AVFrame *frame, SwsContext **m_videoConvertCtx) ;
    int reallocTexture(SDL_Texture **texture, Uint32 new_format, int new_width, int new_height, SDL_BlendMode blendmode, int init_texture);
    void avPixelFormtToSdlFormat(int format, Uint32 *sdl_pix_fmt, SDL_BlendMode *sdl_blendmode);

    //音频
    bool openAudioDevice();
    void closeAudioDevice();
    static void sdlAudioDeviceCallback(void *opaque, Uint8 *stream, int len);
    static int renderNextAudio(RenderThread *pThis);
    static int syncAudio(RenderThread *pThis, int nb_samples);

private:
    VideoPlayer* m_player;
    
    bool m_reqStop;
    bool m_reqPause;
    bool m_lastReqPause;
    bool m_reqStep;
    QString m_lastErrorMsg;

    QWidget* m_widget;
    SDL_Renderer* m_renderer;
    SDL_Window* m_window;   
    SDL_Texture *m_textTexture;
    SDL_Texture *m_videoTexture;
    struct SwsContext *m_videoConvertCtx;
    struct SwsContext *m_textConvertCtx;
    struct SwrContext *m_audioConvertCtx;
    double m_videoFrameTimer;
    QSize m_lastWindowSize;

    SDL_AudioDeviceID m_audioDeviceId;
    double audio_clock;
    int audio_clock_serial;
    double audio_diff_cum;
    double audio_diff_avg_coef;
    double audio_diff_threshold;
    int audio_diff_avg_count;

    struct AudioParams audio_src;
    struct AudioParams audio_tgt;
    int audio_hw_buf_size;
    uint8_t *audio_buf;
    uint8_t *audio_buf1;
    unsigned int audio_buf_size;
    unsigned int audio_buf1_size;
    int audio_buf_index;
    int audio_write_buf_size;

    friend void sdlAudioDeviceCallback(void *opaque, Uint8 *stream, int len);
    friend int renderNextAudio(RenderThread *pThis);
    friend int syncAudio(RenderThread *pThis, int nb_samples);
    friend class VideoPlayer;
};

#endif // RENDERTHREAD_H
